package cn.stylefeng.roses.kernel.sync.modular.ra;

import cn.stylefeng.roses.kernel.sync.core.util.TypeUtil;
import com.alibaba.otter.canal.protocol.CanalEntry;

import java.util.List;

/**
 * 抽象行数据处理者
 *
 * @author fengshuonan
 * @date 2019-01-17-10:09 AM
 */
public abstract class AbstractRowDataAction<T> {

    /**
     * 获取数据库名称
     *
     * @author fengshuonan
     * @Date 2019/1/17 10:10 AM
     */
    public abstract String getTableSchema();

    /**
     * 获取数据库表名称
     *
     * @author fengshuonan
     * @Date 2019/1/17 10:10 AM
     */
    public abstract String getTableName();

    /**
     * 获取变化的表的类类型
     *
     * @author fengshuonan
     * @Date 2019/1/17 5:42 PM
     */
    public abstract Class<T> getTableClass();

    /**
     * 获取事件类型 INSERT UPDATE DELETE CREATE
     *
     * @author fengshuonan
     * @Date 2019/1/17 10:11 AM
     */
    public abstract CanalEntry.EventType getEventType();

    /**
     * 具体逻辑的执行（业务系统编写）
     *
     * @author fengshuonan
     * @Date 2019/1/17 5:39 PM
     */
    public abstract void action(T before, T after);

    /**
     * 判断是否匹配当前的RowDataProcessor
     *
     * @author fengshuonan
     * @Date 2019/1/17 10:34 AM
     */
    public boolean matches(String schema, String tableName, CanalEntry.EventType eventType) {
        if (eventType == this.getEventType()) {
            if (schema.contains(this.getTableSchema())) {
                String name = getTableName();
                if (tableName.equals(name)) {
                    return true;
                }
            }
            if (schema.contains(this.getTableSchema())) {
                String name = getTableName();
                if (tableName.equals(name)) {
                    return true;
                }
            }
        }
        return false;
    }

    /**
     * 处理rowdata数据
     *
     * @author fengshuonan
     * @Date 2019/1/17 10:12 AM
     */
    public void doExecute(CanalEntry.RowData rowData) {

        //获取canal识别到的变化数据
        List<CanalEntry.Column> beforeColumnsList = rowData.getBeforeColumnsList();
        List<CanalEntry.Column> afterColumnsList = rowData.getAfterColumnsList();

        //将canal识别到的数据包装为程序方便操作的数据格式
        T before = TypeUtil.createModel(beforeColumnsList, this.getTableClass());
        T after = TypeUtil.createModel(afterColumnsList, this.getTableClass());

        //执行具体
        if (before != null && after != null) {
            this.action(before, after);
        }
    }

}
